package com.duqc.util;

import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @ClassName DateUtils
 * @Description todo
 * @Author duqc
 * @Date 2021/3/17
 **/
public class DateUtils {

    private static final ConcurrentMap<String, DateTimeFormatter> FORMATTER_CACHE = new ConcurrentHashMap<>();

    private static final int PATTERN_CACHE_SIZE = 500;

    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    private static final String YYYY_MM = "yyyy-MM";

    private static final String[] ZODIAC_ARR = {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"};

    /**
     * 默认时区 东八时区
     */
    private static final String DEFAULT_TIME_ZONE = "GMT+8";

    /**
     * 获取当前字符串时间
     *
     * @return String
     */
    public static String getNow() {
        return format(LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取当前字符串时间
     *
     * @return String
     */
    public static String getNowByPattern(String pattern) {
        return format(LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()), pattern);
    }

    /**
     * Date转换为格式化时间
     *
     * @param date    date
     * @param pattern 格式
     * @return String
     */
    public static String format(Date date, String pattern) {
        return format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()), pattern);
    }

    /**
     * Date转换为格式化时间
     *
     * @param date date
     * @return String
     */
    public static String format(Date date) {
        return format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * localDateTime转换为格式化时间
     *
     * @param localDateTime localDateTime
     * @param pattern       格式
     * @return String
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDateTime.format(formatter);
    }

    /**
     * 格式化字符串转为Date
     *
     * @param time    格式化时间
     * @param pattern 格式
     * @return Date
     */
    public static Date parseDate(String time, String pattern) {
        return Date.from(parseLocalDateTime(time, pattern).atZone(ZoneId.systemDefault()).toInstant());

    }

    /**
     * 格式化字符串转为LocalDateTime
     *
     * @param time    格式化时间
     * @param pattern 格式
     * @return LocalDateTime
     */
    public static LocalDateTime parseLocalDateTime(String time, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalDateTime.parse(time, formatter);
    }

    /**
     * 在缓存中创建DateTimeFormatter
     *
     * @param pattern 格式
     * @return DateTimeFormatter
     */
    private static DateTimeFormatter createCacheFormatter(String pattern) {
        if (pattern == null || pattern.length() == 0) {
            throw new IllegalArgumentException("Invalid pattern specification");
        }
        DateTimeFormatter formatter = FORMATTER_CACHE.get(pattern);
        if (formatter == null) {
            if (FORMATTER_CACHE.size() < PATTERN_CACHE_SIZE) {
                formatter = DateTimeFormatter.ofPattern(pattern);
                DateTimeFormatter oldFormatter = FORMATTER_CACHE.putIfAbsent(pattern, formatter);
                if (oldFormatter != null) {
                    formatter = oldFormatter;
                }
            }
        }

        return formatter;
    }

    /**
     * 获取几周 几月  几天  几年前的数据(格式化到每一秒)
     *
     * @param num  周数
     * @param unit 时间单位 ChronoUnit 枚举类中选择
     * @return String
     */
    public static String getDateByMinus(int num, TemporalUnit unit) {
        return format(LocalDateTime.now().minus(num, unit), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取几周 几月  几天  几年前的数据(格式化到那一天)
     *
     * @param num  周数
     * @param unit 时间单位 ChronoUnit 枚举类中选择
     * @return String
     */
    public static String getDaysByMinus(int num, TemporalUnit unit) {
        return format(LocalDateTime.now().minus(num, unit), "yyyy-MM-dd");
    }

    /**
     * 获取几周 几月  几天  几年前的数据
     *
     * @param num  周数
     * @param unit 时间单位 ChronoUnit 枚举类中选择
     * @return String
     */
    public static String getDateByMinusAndPattern(int num, TemporalUnit unit, String pattern) {
        return format(LocalDateTime.now().minus(num, unit), pattern);
    }

    /**
     * 获取几周 几月  几天  几年后的数据
     *
     * @param num  周数
     * @param unit 时间单位 ChronoUnit 枚举类中选择
     * @return String
     */
    public static String getDateByPlus(int num, TemporalUnit unit) {
        return format(LocalDateTime.now().plus(num, unit), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取几周 几月  几天  几年后的数据
     *
     * @param num  周数
     * @param unit 时间单位 ChronoUnit 枚举类中选择
     * @return String
     */
    public static String getDateByPlusAndPattern(int num, TemporalUnit unit, String pattern) {
        return format(LocalDateTime.now().plus(num, unit), pattern);
    }

    /**
     * 计算两个日期LocalDate相差的天数，不考虑日期前后，返回结果>=0
     *
     * @param before 开始时间
     * @param after  结束时间
     * @return int
     */
    public static int getAbsDateDiffDay(LocalDate before, LocalDate after) {
        return Math.abs(Period.between(before, after).getDays());
    }

    /**
     * 比较两个LocalDateTime是否同一天
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return boolean
     */
    public static boolean isTheSameDay(LocalDateTime begin, LocalDateTime end) {
        return begin.toLocalDate().equals(end.toLocalDate());
    }

    /**
     * 比较两个时间LocalDateTime大小
     *
     * @param time1 时间1
     * @param time2 时间2
     * @return 1:第一个比第二个大；0：第一个与第二个相同；-1：第一个比第二个小
     */
    public static int compareTwoTime(LocalDate time1, LocalDate time2) {
        if (time1.isAfter(time2)) {
            return 1;
        } else if (time1.isBefore(time2)) {
            return -1;
        } else {
            return 0;
        }
    }

    /**
     * 比较两个时间LocalDateTime大小
     *
     * @param time1 时间1
     * @param time2 时间2
     * @return 1:第一个比第二个大；0：第一个与第二个相同；-1：第一个比第二个小
     */
    public static int compareTwoTimeByString(String time1, String time2) {
        LocalDate date1 = LocalDate.parse(time1, DATE_FORMAT);
        LocalDate date2 = LocalDate.parse(time2, DATE_FORMAT);
        return compareTwoTime(date1, date2);
    }

    /**
     * 以当天凌晨为时间点增加天数获得日期
     *
     * @param i 天数(可为负值)
     */
    public static Date addDayAtZero(int i) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        calendar.add(Calendar.DAY_OF_MONTH, i);
        return calendar.getTime();
    }

    /**
     * 以当周凌晨为时间点增加周数获得日期
     *
     * @param i 天数(可为负值)
     */
    public static Date addWeekAtZero(int i) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_WEEK, 2);
        calendar.add(Calendar.WEEK_OF_MONTH, i);
        return calendar.getTime();
    }

    /**
     * 以当月凌晨为时间点增加月数获得日期
     *
     * @param i 天数(可为负值)
     */
    public static Date addMoonAtZero(int i) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, i);
        return calendar.getTime();
    }

    /**
     * 以当年凌晨为时间点增加年数获得日期
     *
     * @param i 天数(可为负值)
     */
    public static Date addYearAtZero(int i) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MONTH, 0);
        calendar.add(Calendar.YEAR, i);
        return calendar.getTime();
    }

    /**
     * 获取当前年
     *
     * @return Integer数据- 年
     */
    public static Integer getCurrentYear() {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取当前月
     *
     * @return int
     */
    public static int getNowMonth() {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取某年某月的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getEndMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(year, month - 1, day);
        return calendar.getTime();
    }

    /**
     * 获取几天后的日期
     *
     * @param num 距离今天的天数 默认 0:表示当前时间
     * @return 时间
     */
    public static Date getDay(Integer num) {
        if (num == null) {
            num = 0;
        }
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + num);
        return calendar.getTime();
    }

    /**
     * 获取几周后的日期
     *
     * @param num 距离今天的周数 默认 0:表示当前时间
     * @return 时间
     */
    public static Date getWeek(Integer num) {
        if (num == null) {
            num = 0;
        }
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) + num);
        return calendar.getTime();
    }

    /**
     * 获取几月后的日期
     *
     * @param num 距离今天的月数 默认 0:表示当前时间
     * @return 时间
     */
    public static Date getMonth(Integer num) {
        if (num == null) {
            num = 0;
        }
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + num);
        return calendar.getTime();
    }

    /**
     * 获取几年后的日期
     *
     * @param num 距离今天的年数 默认 0:表示当前时间
     * @return 时间
     */
    public static Date getYear(Integer num) {
        if (num == null) {
            num = 0;
        }
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + num);
        return calendar.getTime();
    }

    /**
     * 根据日期获取生肖
     *
     * @return String
     */
    public static String getZodiac(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return ZODIAC_ARR[cal.get(Calendar.YEAR) % 12];
    }

    /**
     * 获取某个日期的开始时间
     *
     * @param d 日期
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Timestamp getDayBeginTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取某个日期的结束时间
     *
     * @param d 日期
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取本周的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfWeek() {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayBeginTime(cal.getTime());
    }

    /**
     * 获取本周的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    /**
     * 获取上周的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfBeforeWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.add(Calendar.DATE, -7);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取指定时间所在周的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfWeekByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayBeginTime(cal.getTime());
    }


    /**
     * 获取指定时间所在周的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfWeekByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeekByDate(date));
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    /**
     * 获取上周的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfBeforeWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.add(Calendar.DATE, -7);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取下月的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfNextMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth(), 1);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取下月的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfNextMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth(), 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getCurrentYear(), getNowMonth(), day);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取本月的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth() - 1, 1);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取本月的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getCurrentYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取指定月的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static String getMonthEnd(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD);
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date resultDate = c.getTime();
        return sdf.format(resultDate);
    }

    /**
     * 获取指定月的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static String getMonthBegin(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM);
        String string = sdf.format(date);
        return string + "-01";
    }

    /**
     * 获取近num月或将来num月的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfMonth(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth() + num, 1);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取近num月或将来num月的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfMonth(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getCurrentYear(), getNowMonth() + num, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getCurrentYear(), getNowMonth() + num, day);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取上月的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfBeforeMonth() {
        //获取当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取上月的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfBeforeMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取明年的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfNextYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear() + 1);
        // cal.set
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);

        return getDayBeginTime(cal.getTime());
    }

    /**
     * 获取去年的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfLastYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear() - 1);
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayBeginTime(cal.getTime());
    }

    /**
     * 获取去年的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfLastYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear() - 1);
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }

    /**
     * 获取num年的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfNumYear(int num) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear() + num);
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayBeginTime(cal.getTime());
    }

    /**
     * 获取明年年的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfNextYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear() + 1);
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }

    /**
     * 获取当前季度的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfQuarter() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear());
        int month = getNowMonth() - 1;
        int beginMonth = (month / 3) * 3;
        cal.set(Calendar.MONTH, beginMonth);
        cal.set(Calendar.DATE, 1);

        return getDayBeginTime(cal.getTime());
    }

    /**
     * 获取当前季度的结束时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getEndDayOfQuarter() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getCurrentYear());
        int month = getNowMonth() - 1;
        int endMonth = ((month / 3) + 1) * 3;
        return getEndMonthDate(getCurrentYear(), endMonth);
    }

    /**
     * 两个日期相减得到的天数
     *
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return int
     */
    public static int getDiffDays(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null) {
            throw new IllegalArgumentException("getDiffDays param is null!");
        }
        long diff = (endDate.getTime() - beginDate.getTime())
                / (1000 * 60 * 60 * 24);
        return (int) diff;
    }

    /**
     * 两个日期相减得到的毫秒数
     *
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return long
     */
    public static long dateDiff(Date beginDate, Date endDate) {
        long date1ms = beginDate.getTime();
        long date2ms = endDate.getTime();
        return date2ms - date1ms;
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 两个日期相减得到的毫秒数
     *
     * @param endDate 结束时间
     * @param nowDate 开始时间
     * @return String
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60L;
        long nh = 1000 * 60 * 60L;
        long nm = 1000 * 60L;
        long diff = endDate.getTime() - nowDate.getTime();
        long day = diff / nd;
        long hour = diff % nd / nh;
        long min = diff % nd % nh / nm;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 获取近多少个月的所有月份
     *
     * @param date 当前月份
     * @param num  近多少个月
     * @return
     */
    public static List<String> getNumMonth(int date, int num) {
        List<String> list = new ArrayList<>();
        for (int i = num - 1; i >= 0; i--) {
            if (date > num) {
                if (date - i >= 10) {
                    list.add(String.valueOf(date - i));
                } else {
                    list.add("0" + (date - i));
                }
            } else {
                if (date - i <= 0) {
                    if (date - i + 12 >= 10) {
                        list.add(String.valueOf(date - i + 12));
                    } else {
                        list.add("0" + (date - i + 12));
                    }
                } else {
                    if (date - i >= 10) {
                        list.add(String.valueOf(date - i));
                    } else {
                        list.add("0" + (date - i));
                    }
                }
            }
        }
        return list;
    }

    /**
     * 获取过去n周的开始时间
     *
     * @return yyyy-MM-dd HH:mm:ss  格式
     */
    public static Date getBeginDayOfSomeWeek(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.add(Calendar.DATE, -7 * num);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return getDayBeginTime(calendar.getTime());
    }

    /**
     * 获取当前年、当前周的开始时间
     *
     * @param year   年
     * @param weekNo 周
     * @return string
     */
    public static String getStartDayOfWeekNo(int year, int weekNo) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" +
                cal.get(Calendar.DAY_OF_MONTH);

    }

    /**
     * 获取当前年、当前周的结束时间
     *
     * @param year   年
     * @param weekNo 周
     * @return string
     */
    public static String getEndDayOfWeekNo(int year, int weekNo) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        cal.add(Calendar.DAY_OF_WEEK, 6);
        return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" +
                cal.get(Calendar.DAY_OF_MONTH);
    }

}
